function initApp() {
  // 主题切换
  const themeBtns = document.querySelectorAll('[data-theme]');
  const themeToggle = document.getElementById('themeToggle');

  function applyTheme(mode) {
    if (mode === 'auto') {
      document.documentElement.removeAttribute('data-theme');
      localStorage.removeItem('theme');
    } else {
      document.documentElement.setAttribute('data-theme', mode);
      localStorage.setItem('theme', mode);
    }
  }

  const savedTheme = localStorage.getItem('theme');
  if (savedTheme) applyTheme(savedTheme);

  themeBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      themeBtns.forEach(b => b.classList.remove('seg-active'));
      btn.classList.add('seg-active');
      applyTheme(btn.dataset.theme);
    });
  });

  if (themeToggle) {
    themeToggle.addEventListener('click', () => {
      const current = document.documentElement.getAttribute('data-theme') || 'auto';
      const next = current === 'light' ? 'dark' : current === 'dark' ? 'auto' : 'light';
      applyTheme(next);
    });
  }

  // 文件上传功能
  function createUploadHandler(dataType) {
    const uploadArea = document.getElementById(`${dataType}UploadArea`);
    const fileInput = document.getElementById(`${dataType}FileInput`);
    const uploadProgress = document.getElementById(`${dataType}UploadProgress`);
    const uploadResult = document.getElementById(`${dataType}UploadResult`);
    const clearBtn = document.getElementById(`${dataType}ClearUpload`);
    const processBtn = document.getElementById(`${dataType}ProcessFile`);
    const progressFill = document.getElementById(`${dataType}ProgressFill`);
    const progressText = document.getElementById(`${dataType}ProgressText`);
    const resultTitle = document.getElementById(`${dataType}ResultTitle`);
    const resultDetail = document.getElementById(`${dataType}ResultDetail`);

    if (!uploadArea || !fileInput) return;

    uploadArea.addEventListener('click', () => fileInput.click());

    uploadArea.addEventListener('dragover', (e) => {
      e.preventDefault();
      uploadArea.classList.add('dragover');
    });

    uploadArea.addEventListener('dragleave', () => {
      uploadArea.classList.remove('dragover');
    });

    uploadArea.addEventListener('drop', (e) => {
      e.preventDefault();
      uploadArea.classList.remove('dragover');
      const files = e.dataTransfer.files;
      if (files.length > 0) handleFileUpload(files[0]);
    });

    fileInput.addEventListener('change', (e) => {
      if (e.target.files.length > 0) handleFileUpload(e.target.files[0]);
    });

    async function handleFileUpload(file) {
      if (!isValidFile(file)) {
        showResult(false, '文件格式错误', '请上传 .xlsx 或 .xls 格式的文件');
        return;
      }

      if (file.size > 10 * 1024 * 1024) {
        showResult(false, '文件过大', '文件大小不能超过 10MB');
        return;
      }

      uploadProgress.style.display = 'flex';
      uploadResult.style.display = 'none';

      const formData = new FormData();
      formData.append('file', file);

      try {
        let progress = 0;
        const progressInterval = setInterval(() => {
          progress += Math.random() * 20;
          if (progress > 90) progress = 90;
          updateProgress(progress);
        }, 100);

        const response = await fetch(`/api/upload/${dataType}`, {
          method: 'POST',
          body: formData
        });

        clearInterval(progressInterval);
        updateProgress(100);

        const result = await response.json();

        setTimeout(() => {
          uploadProgress.style.display = 'none';
          if (result.success) {
            showResult(true, '上传成功', `${result.message}，处理了 ${result.rows} 行数据`);
            clearBtn.style.display = 'inline-block';
            processBtn.style.display = 'inline-block';
          } else {
            showResult(false, '上传失败', result.message || '请稍后重试');
          }
        }, 500);

      } catch (error) {
        uploadProgress.style.display = 'none';
        showResult(false, '上传失败', '网络异常，请检查连接');
      }
    }

    function isValidFile(file) {
      const validTypes = [
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/vnd.ms-excel'
      ];
      return validTypes.includes(file.type) || 
             file.name.toLowerCase().endsWith('.xlsx') || 
             file.name.toLowerCase().endsWith('.xls');
    }

    function updateProgress(percent) {
      progressFill.style.width = `${percent}%`;
      progressText.textContent = `${Math.round(percent)}%`;
    }

    function showResult(success, title, detail) {
      uploadResult.style.display = 'flex';
      uploadResult.className = `upload-result ${success ? '' : 'error'}`;
      resultTitle.textContent = title;
      resultDetail.textContent = detail;
    }

    if (clearBtn) {
      clearBtn.addEventListener('click', () => {
        fileInput.value = '';
        uploadResult.style.display = 'none';
        clearBtn.style.display = 'none';
        processBtn.style.display = 'none';
      });
    }

    if (processBtn) {
      processBtn.addEventListener('click', () => {
        const typeNames = {
          'delivery': '交付数据',
          'workload': '工作量数据',
          'defect': '缺陷数据'
        };
        alert(`${typeNames[dataType]}处理功能开发中...`);
      });
    }
  }

  // 初始化所有功能
  function initFileUpload() {
    createUploadHandler('delivery');
    createUploadHandler('workload');
    createUploadHandler('defect');
  }

  function initTemplateDownload() {
    const templateBtns = document.querySelectorAll('.template-btn');
    templateBtns.forEach(btn => {
      btn.addEventListener('click', async () => {
        const templateType = btn.dataset.template;
        try {
          const response = await fetch(`/api/template/${templateType}`);
          if (response.ok) {
            const blob = await response.blob();
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${templateType}_template.csv`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);
            
            btn.textContent = '下载完成 ✓';
            setTimeout(() => { btn.textContent = '下载模板'; }, 2000);
          }
        } catch (error) {
          btn.textContent = '下载失败';
          setTimeout(() => { btn.textContent = '下载模板'; }, 2000);
        }
      });
    });
  }

  function initDateFilter() {
    const startDate = document.getElementById('startDate');
    const endDate = document.getElementById('endDate');
    const quickBtns = document.querySelectorAll('.quick-btn');
    const applyBtn = document.getElementById('applyFilter');
    const resetBtn = document.getElementById('resetFilter');

    if (!startDate || !endDate) return;

    const today = new Date();
    const thirtyDaysAgo = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);
    
    endDate.value = today.toISOString().split('T')[0];
    startDate.value = thirtyDaysAgo.toISOString().split('T')[0];

    quickBtns.forEach(btn => {
      btn.addEventListener('click', () => {
        quickBtns.forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        
        const days = parseInt(btn.dataset.range);
        const endDate_val = new Date();
        const startDate_val = new Date(endDate_val.getTime() - days * 24 * 60 * 60 * 1000);
        
        startDate.value = startDate_val.toISOString().split('T')[0];
        endDate.value = endDate_val.toISOString().split('T')[0];
      });
    });

    if (applyBtn) {
      applyBtn.addEventListener('click', () => {
        const start = startDate.value;
        const end = endDate.value;
        
        if (start && end) {
          loadPerformanceData(start, end);
          applyBtn.textContent = '已应用 ✓';
          setTimeout(() => { applyBtn.textContent = '应用筛选'; }, 1500);
        }
      });
    }

    if (resetBtn) {
      resetBtn.addEventListener('click', () => {
        const endDateVal = new Date();
        const startDateVal = new Date(endDateVal.getTime() - 30 * 24 * 60 * 60 * 1000);
        startDate.value = startDateVal.toISOString().split('T')[0];
        endDate.value = endDateVal.toISOString().split('T')[0];

        quickBtns.forEach(b => b.classList.remove('active'));
        const btn30 = Array.from(quickBtns).find(b => b.dataset.range === '30');
        if (btn30) btn30.classList.add('active');

        loadPerformanceData(startDate.value, endDate.value);
        resetBtn.textContent = '已重置 ✓';
        setTimeout(() => { resetBtn.textContent = '重置'; }, 1500);
      });
    }

    loadPerformanceData(startDate.value, endDate.value);
  }

  // 替换现有的 loadPerformanceData 函数（第265-297行）
  async function loadPerformanceData(startDate, endDate) {
      if (!document.getElementById('totalThroughput')) {
          console.warn('找不到性能指标容器');
          return;
      }
      
      try {
          console.log('📊 开始加载效能数据...', {startDate, endDate});
          
          const url = `/api/performance?start_date=${startDate}&end_date=${endDate}`;
          console.log('🌐 请求URL:', url);
          
          const response = await fetch(url);
          console.log('📡 响应状态:', response.status, response.statusText);
          
          if (!response.ok) {
              throw new Error(`HTTP ${response.status}: ${response.statusText}`);
          }
          
          const data = await response.json();
          console.log('✅ 收到完整数据:', {
              delivery_stats: data.delivery_stats,
              ft_projects: data.ft_projects,
              delayed_requirements: data.delayed_requirements,
              workload_stats: data.workload_stats,
              defect_stats: data.defect_stats
          });
          
          // 检查数据是否为空
          if (!data.delivery_stats || data.delivery_stats.new_requirements === 0) {
              console.warn('⚠️ 交付数据为空，请检查是否上传了交付文件');
          }
          if (!data.workload_stats || data.workload_stats.length === 0) {
              console.warn('⚠️ 工作量数据为空，请检查是否上传了工作量文件');
          }
          if (!data.defect_stats || data.defect_stats.total_defects === 0) {
              console.warn('⚠️ 缺陷数据为空，请检查是否上传了缺陷文件');
          }
          
          // 更新所有数据
          updateDeliveryMetrics(data.delivery_stats || {new_requirements: 0, delivered_requirements: 0, throughput_rate: 0});
          updateFTProjectTable(data.ft_projects || []);
          updateDelayedRequirementsTable(data.delayed_requirements || []);
          updateWorkloadTable(data.workload_stats || []);
          
          // 关键：更新缺陷数据展示
        if (data.defect_stats) {
            updateDefectStats(data.defect_stats);
        }
        
        // 存储数据供AI分析使用
        window.currentPerformanceData = data;
        
    } catch (error) {
        console.error('❌ 加载效能数据失败:', error);
        alert('数据加载失败: ' + error.message + '\n请检查控制台获取详细信息');
    }
}

  function updateDeliveryMetrics(stats) {
    const totalThroughput = document.getElementById('totalThroughput');
    const newRequirements = document.getElementById('newRequirements');
    const deliveredRequirements = document.getElementById('deliveredRequirements');

    if (totalThroughput) totalThroughput.textContent = `${stats.throughput_rate.toFixed(1)}%`;
    if (newRequirements) newRequirements.textContent = stats.new_requirements;
    if (deliveredRequirements) deliveredRequirements.textContent = stats.delivered_requirements;
  }

  // 简化后的更新函数
  let ftProjectPagination = null;
  function updateFTProjectTable(projects) {
      const ftTable = document.getElementById('ftProjectTable');
      if (!ftTable) return;
  
      if (!ftProjectPagination) {
          ftProjectPagination = createPaginationManager('ftProjectTable', projects || [], 10);
      } else {
          ftProjectPagination.setData(projects || []);
      }
  }
  
  let delayedReqPagination = null;
  function updateDelayedRequirementsTable(delayedReqs) {
      const delayedTable = document.getElementById('delayedRequirementsTable');
      if (!delayedTable) return;
  
      if (!delayedReqPagination) {
          delayedReqPagination = createPaginationManager('delayedRequirementsTable', delayedReqs || [], 10);
      } else {
          delayedReqPagination.setData(delayedReqs || []);
      }
  }
  
  let workloadPagination = null;
  function updateWorkloadTable(workloadData) {
      const workloadTable = document.getElementById('workloadTable');
      if (!workloadTable) return;
  
      if (!workloadPagination) {
          workloadPagination = createPaginationManager('workloadTable', workloadData || [], 10);
      } else {
          workloadPagination.setData(workloadData || []);
      }
  }

  // 添加表格数据渲染函数
  // 删除或注释掉以下函数（第359-421行）
  /*
  function renderTableData(table, data) {
    const tableId = table.id;
    
    if (tableId === 'ftProjectTable') {
      if (data && data.length > 0) {
        table.innerHTML = data.map(project => `
          <tr>
            <td>${project.project_name}</td>
            <td>${project.throughput_rate}%</td>
            <td>${project.new_requirements}</td>
            <td>${project.delivered_requirements}</td>
          </tr>
        `).join('');
      } else {
        table.innerHTML = '<tr><td colspan="4" style="text-align: center; color: var(--muted);">暂无数据</td></tr>';
      }
    } else if (tableId === 'delayedRequirementsTable') {
      if (data && data.length > 0) {
        table.innerHTML = data.map(req => `
          <tr>
            <td>${req.requirement_name}</td>
            <td>${req.ft_name}</td>
            <td>${req.system}</td>
            <td>${req.pm}</td>
            <td>${req.rd}</td>
            <td>${req.fe}</td>
            <td>${req.qa}</td>
          </tr>
        `).join('');
      } else {
        table.innerHTML = '<tr><td colspan="7" style="text-align: center; color: var(--muted);">暂无延期需求</td></tr>';
      }
    } else if (tableId === 'workloadTable') {
      if (data && data.length > 0) {
        table.innerHTML = data.map(item => `
          <tr>
            <td>${item.user_name}</td>
            <td>${item.saturation}%</td>
            <td>${item.code_equivalent}</td>
            <td>${item.total_hours}h</td>
            <td>${item.ai_active_days}天</td>
          </tr>
        `).join('');
      } else {
        table.innerHTML = '<tr><td colspan="5" style="text-align: center; color: var(--muted);">暂无工作量数据</td></tr>';
      }
    }
  }
  */

  function updateTables() {
    const ftTable = document.getElementById('ftProjectTable');
    if (ftTable) {
      ftTable.innerHTML = '<tr><td colspan="4" style="text-align: center; color: var(--muted);">暂无数据</td></tr>';
    }

    updateDelayedRequirementsTable([]);

    const workloadTable = document.getElementById('workloadTable');
    if (workloadTable) {
      workloadTable.innerHTML = '<tr><td colspan="5" style="text-align: center; color: var(--muted);">暂无数据</td></tr>';
    }
  }

  function updateMetrics() {
    const totalThroughput = document.getElementById('totalThroughput');
    const newRequirements = document.getElementById('newRequirements');
    const deliveredRequirements = document.getElementById('deliveredRequirements');

    if (totalThroughput) totalThroughput.textContent = '—';
    if (newRequirements) newRequirements.textContent = '—';
    if (deliveredRequirements) deliveredRequirements.textContent = '—';
  }

  async function loadKPIs() {
    const kpiElements = document.getElementById('kpiThroughput');
    if (!kpiElements) return;
  
    try {
      const res = await fetch('/api/performance');
      const data = await res.json();
      const [t, l, e] = data.kpis;
  
      const throughputEl = document.getElementById('kpiThroughput');
      const throughputTrendEl = document.getElementById('kpiThroughputTrend');
      const latencyEl = document.getElementById('kpiLatency');
      const latencyTrendEl = document.getElementById('kpiLatencyTrend');
      const errorEl = document.getElementById('kpiError');
      const errorTrendEl = document.getElementById('kpiErrorTrend');
  
      if (throughputEl) throughputEl.textContent = t.value;
      if (throughputTrendEl) throughputTrendEl.textContent = t.trend;
      if (latencyEl) latencyEl.textContent = l.value;
      if (latencyTrendEl) latencyTrendEl.textContent = l.trend;
      if (errorEl) errorEl.textContent = e.value;
      if (errorTrendEl) errorTrendEl.textContent = e.trend;
    } catch (err) {
      console.error('加载KPI失败:', err);
    }
  }

  function bindAIReport() {
    const btn = document.getElementById('btnGenerate');
    if (!btn) return;

    btn.addEventListener('click', async () => {
      const topic = document.getElementById('reportTopic').value.trim() || '效能周报';
      const focus = document.getElementById('reportFocus').value.trim();
      const output = document.getElementById('reportOutput');

      output.textContent = '正在生成报告...';

      try {
        const res = await fetch('/api/ai/report', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ topic, focus })
        });
        const data = await res.json();
        output.textContent = data.report || '生成失败，请稍后重试。';
      } catch (e) {
        output.textContent = '服务异常，请检查后端日志。';
      }
    });
  }

  function bindSettings() {
    const btnSave = document.getElementById('saveSettings');
    if (!btnSave) return;

    btnSave.addEventListener('click', () => {
      const interval = document.getElementById('refreshInterval').value;
      const apiKey = document.getElementById('apiKey').value.trim();
      const motion = document.getElementById('motionToggle').checked;
  
      localStorage.setItem('settings', JSON.stringify({ interval, apiKey, motion }));
      btnSave.textContent = '已保存 ✓';
      setTimeout(() => (btnSave.textContent = '保存设置'), 1200);
    });
  
    const saved = localStorage.getItem('settings');
    if (saved) {
      const conf = JSON.parse(saved);
      document.getElementById('refreshInterval').value = conf.interval;
      document.getElementById('apiKey').value = conf.apiKey;
      document.getElementById('motionToggle').checked = conf.motion;
    }
  }

  function bindAIButton() {
    const btn = document.getElementById('aiAnalyze');
    if (!btn) return;
    
    btn.addEventListener('click', async () => {
      const startDate = document.getElementById('startDate')?.value;
      const endDate = document.getElementById('endDate')?.value;
      
      if (!startDate || !endDate) {
        alert('请先选择时间范围');
        return;
      }

      const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
      if (!dateRegex.test(startDate) || !dateRegex.test(endDate)) {
            alert('日期格式错误，请使用 YYYY-MM-DD 格式');
            return;
        }

        // 检查是否有数据
        if (!window.currentPerformanceData) {
            alert('请先加载数据再进行分析');
            return;
        }

        btn.textContent = '🔄 分析中...';
        btn.disabled = true;

        try {
            const aiResponse = await fetch('/api/ai-analyze', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(window.currentPerformanceData)
            });

            if (!aiResponse.ok) {
                throw new Error(`HTTP ${aiResponse.status}: ${aiResponse.statusText}`);
            }

            const aiData = await aiResponse.json();
            
            if (aiData.success) {
                // 关键修复：只存储analysis对象，确保格式正确
                const reportData = {
                    summary: aiData.analysis.summary,
                    timestamp: aiData.analysis.timestamp,
                    data_summary: aiData.analysis.data_summary
                };
                localStorage.setItem('aiAnalysisResult', JSON.stringify(reportData));
                window.location.href = '/ai_report';
            } else {
                alert('AI分析失败: ' + (aiData.message || '未知错误'));
            }
        } catch (error) {
            console.error('错误:', error);
            alert('网络连接失败，请检查后端服务是否启动');
        } finally {
            btn.textContent = '🤖 AI分析';
            btn.disabled = false;
        }
    });
  }

  // 初始化所有功能
  initFileUpload();
  initTemplateDownload();
  initDateFilter();
  loadKPIs();
  bindAIReport();
  bindSettings();
  bindAIButton();
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', initApp);

// 在initApp函数内添加通用分页管理器
function createPaginationManager(tableId, data, pageSize = 10) {
    let currentPage = 1;
    let paginatedData = Array.isArray(data) ? data : [];
    
    // 确保表格存在
    const table = document.getElementById(tableId);
    if (!table) {
        console.error(`❌ 表格 ${tableId} 不存在`);
        return { setData: () => {}, renderPage: () => {} };
    }
    
    // 内置渲染函数 - 解决作用域问题
    function renderTableContent(targetTable, pageData) {
        if (tableId === 'ftProjectTable') {
            if (pageData && pageData.length > 0) {
                targetTable.innerHTML = pageData.map(project => `
                    <tr>
                        <td>${project.project_name}</td>
                        <td>${project.throughput_rate}%</td>
                        <td>${project.new_requirements}</td>
                        <td>${project.delivered_requirements}</td>
                    </tr>
                `).join('');
            } else {
                targetTable.innerHTML = '<tr><td colspan="4" style="text-align: center; color: var(--muted); padding: 40px;">暂无数据</td></tr>';
            }
        } else if (tableId === 'delayedRequirementsTable') {
            if (pageData && pageData.length > 0) {
                targetTable.innerHTML = pageData.map(req => `
                    <tr>
                        <td>${req.requirement_name}</td>
                        <td>${req.ft_name}</td>
                        <td>${req.system}</td>
                        <td>${req.pm}</td>
                        <td>${req.rd}</td>
                        <td>${req.fe}</td>
                        <td>${req.qa}</td>
                    </tr>
                `).join('');
            } else {
                targetTable.innerHTML = '<tr><td colspan="7" style="text-align: center; color: var(--muted); padding: 40px;">暂无延期需求</td></tr>';
            }
        } else if (tableId === 'workloadTable') {
            if (pageData && pageData.length > 0) {
                targetTable.innerHTML = pageData.map(item => `
                    <tr>
                        <td>${item.user_name}</td>
                        <td>${item.saturation}%</td>
                        <td>${item.code_equivalent}</td>
                        <td>${item.total_hours}天</td>
                        <td>${item.ai_active_days}天</td>
                    </tr>
                `).join('');
            } else {
                targetTable.innerHTML = '<tr><td colspan="5" style="text-align: center; color: var(--muted); padding: 40px;">暂无工作量数据</td></tr>';
            }
        }
    }
    
    // 初始化分页控制
    initPaginationControls();
    
    function initPaginationControls() {
        // 移除旧的分页控制
        const existingControls = table.parentElement.querySelector('.pagination-controls');
        if (existingControls) {
            existingControls.remove();
        }
        
        // 创建新的分页容器
        const paginationDiv = document.createElement('div');
        paginationDiv.className = 'pagination-controls';
        paginationDiv.style.cssText = `
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 16px 0;
            padding: 12px;
            background: var(--card-bg);
            border-radius: 8px;
            font-size: 14px;
            border: 1px solid var(--border);
        `;
        
        paginationDiv.innerHTML = `
            <div class="pagination-info">
                共 <span id="${tableId}TotalCount">0</span> 条记录，
                第 <span id="${tableId}CurrentPage">1</span> / <span id="${tableId}TotalPages">1</span> 页
            </div>
            <div class="pagination-buttons">
                <button id="${tableId}PrevBtn" class="btn btn-sm" disabled>上一页</button>
                <span id="${tableId}PageNumbers"></span>
                <button id="${tableId}NextBtn" class="btn btn-sm">下一页</button>
                <select id="${tableId}PageSize" class="select-sm" style="margin-left: 8px;">
                    <option value="10">10条/页</option>
                    <option value="20">20条/页</option>
                    <option value="50">50条/页</option>
                </select>
            </div>
        `;
        
        table.parentElement.appendChild(paginationDiv);
        
        // 绑定事件（使用事件委托避免重复绑定）
        setTimeout(() => {
            const prevBtn = document.getElementById(`${tableId}PrevBtn`);
            const nextBtn = document.getElementById(`${tableId}NextBtn`);
            const pageSizeSelect = document.getElementById(`${tableId}PageSize`);
            
            prevBtn?.addEventListener('click', () => goToPage(currentPage - 1));
            nextBtn?.addEventListener('click', () => goToPage(currentPage + 1));
            pageSizeSelect?.addEventListener('change', (e) => {
                pageSize = parseInt(e.target.value);
                currentPage = 1;
                renderPage();
            });
        }, 0);
    }
    
    function goToPage(page) {
        const totalPages = Math.ceil(paginatedData.length / pageSize);
        if (page < 1 || page > totalPages) return;
        currentPage = page;
        renderPage();
    }
    
    function renderPage() {
        if (paginatedData.length === 0) {
            renderTableContent(table, []);
            return;
        }
        
        const startIndex = (currentPage - 1) * pageSize;
        const endIndex = startIndex + pageSize;
        const pageData = paginatedData.slice(startIndex, endIndex);
        
        renderTableContent(table, pageData);
        
        const totalPages = Math.ceil(paginatedData.length / pageSize);
        
        // 更新分页信息
        const totalCountEl = document.getElementById(`${tableId}TotalCount`);
        const currentPageEl = document.getElementById(`${tableId}CurrentPage`);
        const totalPagesEl = document.getElementById(`${tableId}TotalPages`);
        
        if (totalCountEl) totalCountEl.textContent = paginatedData.length;
        if (currentPageEl) currentPageEl.textContent = currentPage;
        if (totalPagesEl) totalPagesEl.textContent = totalPages;
        
        // 更新按钮状态
        const prevBtn = document.getElementById(`${tableId}PrevBtn`);
        const nextBtn = document.getElementById(`${tableId}NextBtn`);
        
        if (prevBtn) prevBtn.disabled = currentPage === 1;
        if (nextBtn) nextBtn.disabled = currentPage === totalPages;
        
        updatePageNumbers(totalPages);
    }
    
    function updatePageNumbers(totalPages) {
        const container = document.getElementById(`${tableId}PageNumbers`);
        if (!container) return;
        
        container.innerHTML = '';
        
        const maxVisiblePages = 5;
        let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
        let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
        
        if (endPage - startPage < maxVisiblePages - 1) {
            startPage = Math.max(1, endPage - maxVisiblePages + 1);
        }
        
        for (let i = startPage; i <= endPage; i++) {
            const pageBtn = document.createElement('button');
            pageBtn.className = `btn btn-sm ${i === currentPage ? 'active' : ''}`;
            pageBtn.style.cssText = `
                margin: 0 2px;
                padding: 4px 8px;
                min-width: 32px;
                background: ${i === currentPage ? 'var(--primary)' : 'transparent'};
                color: ${i === currentPage ? 'white' : 'var(--text)'};
                border: 1px solid var(--border);
                border-radius: 4px;
                cursor: pointer;
            `;
            pageBtn.textContent = i;
            pageBtn.addEventListener('click', () => goToPage(i));
            container.appendChild(pageBtn);
        }
    }
    
    return {
        setData: (newData) => {
            paginatedData = Array.isArray(newData) ? newData : [];
            currentPage = 1;
            initPaginationControls();
            renderPage();
        },
        renderPage
    };
}

// 替换现有的 loadPerformanceData 函数（合并两个版本）
async function loadPerformanceData(startDate, endDate) {
    if (!document.getElementById('totalThroughput')) {
        console.warn('找不到性能指标容器');
        return;
    }
    
    try {
        console.log('📊 开始加载效能数据...', {startDate, endDate});
        
        const url = `/api/performance?start_date=${startDate}&end_date=${endDate}`;
        console.log('🌐 请求URL:', url);
        
        const response = await fetch(url);
        console.log('📡 响应状态:', response.status, response.statusText);
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const data = await response.json();
        console.log('✅ 收到完整数据:', {
            delivery_stats: data.delivery_stats,
            ft_projects: data.ft_projects,
            delayed_requirements: data.delayed_requirements,
            workload_stats: data.workload_stats,
            defect_stats: data.defect_stats
        });
        
        // 检查数据是否为空
        if (!data.delivery_stats || data.delivery_stats.new_requirements === 0) {
            console.warn('⚠️ 交付数据为空，请检查是否上传了交付文件');
        }
        if (!data.workload_stats || data.workload_stats.length === 0) {
            console.warn('⚠️ 工作量数据为空，请检查是否上传了工作量文件');
        }
        if (!data.defect_stats || data.defect_stats.total_defects === 0) {
            console.warn('⚠️ 缺陷数据为空，请检查是否上传了缺陷文件');
        }
        
        // 更新所有数据
        updateDeliveryMetrics(data.delivery_stats || {new_requirements: 0, delivered_requirements: 0, throughput_rate: 0});
        updateFTProjectTable(data.ft_projects || []);
        updateDelayedRequirementsTable(data.delayed_requirements || []);
        updateWorkloadTable(data.workload_stats || []);
        
        // 更新缺陷数据展示
        if (data.defect_stats) {
            updateDefectStats(data.defect_stats);
        }
        
    } catch (error) {
        console.error('❌ 加载效能数据失败:', error);
        alert('数据加载失败: ' + error.message + '\n请检查控制台获取详细信息');
    }
}

// 添加缺陷数据展示函数
function updateDefectStats(defectStats) {
    // 1. 更新总缺陷数方块
    document.getElementById('total-defects').textContent = defectStats.total_defects;
    
    // 2. 更新不同状态缺陷总数方块
    updateDefectStatusSquares(defectStats.status_stats);
    
    // 3. 更新不同优先级缺陷总数方块
    updateDefectPrioritySquares(defectStats.priority_stats);
    
    // 4. 更新缺陷状态分布图
    updateDefectStatusChart(defectStats.status_stats);
    
    // 5. 更新缺陷优先级分布图
    updateDefectPriorityChart(defectStats.priority_stats);
    
    // 6. 更新业务线缺陷柱状图
    renderFtDefectChart(defectStats.ft_defect_stats);
    
    // 7. 更新创建人缺陷柱状图
    renderCreatorChart(defectStats.creator_stats);
    
    // 8. 更新最近缺陷列表
    updateDefectList(defectStats.defect_list);
}

// 替换现有的updateDefectStatusSquares函数
function updateDefectStatusSquares(statusStats) {
    // 新的状态映射
    const statusMapping = {
        '待排查': 'pending-investigation',
        '未复现': 'not-reproduced',
        '待处理': 'pending-processing',
        '重新打开': 'reopened',
        '已打开': 'opened',
        '延期处理': 'delayed-processing',
        '待验证': 'pending-verification',
        '已关闭': 'closed-defects'
    };
    
    // 重置所有方块为0
    const statusIds = [
        'pending-investigation', 'not-reproduced', 'pending-processing', 
        'reopened', 'opened', 'delayed-processing', 'pending-verification', 
        'closed-defects', 'other-status'
    ];
    
    statusIds.forEach(id => {
        const element = document.getElementById(id);
        if (element) element.textContent = '0';
    });
    
    // 更新实际数据
    let otherCount = 0;
    Object.entries(statusStats).forEach(([status, count]) => {
        const elementId = statusMapping[status];
        if (elementId) {
            const element = document.getElementById(elementId);
            if (element) element.textContent = count;
        } else {
            // 统计未匹配的状态
            otherCount += count;
        }
    });
    
    // 更新其他状态
    const otherElement = document.getElementById('other-status');
    if (otherElement && otherCount > 0) {
        otherElement.textContent = otherCount;
    }
}

// 替换现有的updateDefectPrioritySquares函数
function updateDefectPrioritySquares(priorityStats) {
    // 新的优先级映射
    const priorityMapping = {
        'P0': 'p0-defects',
        'P1': 'p1-defects',
        'P2': 'p2-defects',
        'P3': 'p3-defects',
        'P4': 'p4-defects',
        'P5': 'p5-defects',
        '紧急': 'p0-defects',
        '高': 'p1-defects',
        '中': 'p2-defects',
        '低': 'p3-defects'
    };
    
    // 重置所有方块为0
    const priorityIds = ['p0-defects', 'p1-defects', 'p2-defects', 'p3-defects', 'p4-defects', 'p5-defects'];
    priorityIds.forEach(id => {
        const element = document.getElementById(id);
        if (element) element.textContent = '0';
    });
    
    // 更新实际数据
    Object.entries(priorityStats).forEach(([priority, count]) => {
        const elementId = priorityMapping[priority];
        if (elementId) {
            const element = document.getElementById(elementId);
            if (element) {
                const current = parseInt(element.textContent) || 0;
                element.textContent = current + count;
            }
        }
    });
}

// 添加业务线缺陷柱状图
function renderFtDefectChart(ftDefectStats) {
    const ctx = document.getElementById('ft-defect-chart');
    if (!ctx) return;
    
    // 按缺陷数量降序排序，取前10
    const sortedData = ftDefectStats
        .sort((a, b) => b.total_defects - a.total_defects)
        .slice(0, 10);
    
    const labels = sortedData.map(item => item.ft_name);
    const totalData = sortedData.map(item => item.total_defects);
    const openData = sortedData.map(item => item.open_defects);
    const closedData = sortedData.map(item => item.closed_defects);
    
    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [
                {
                    label: '总缺陷数',
                    data: totalData,
                    backgroundColor: 'rgba(255, 99, 132, 0.6)',
                    borderColor: 'rgba(255, 99, 132, 1)',
                    borderWidth: 1
                },
                {
                    label: '未解决',
                    data: openData,
                    backgroundColor: 'rgba(255, 206, 86, 0.6)',
                    borderColor: 'rgba(255, 206, 86, 1)',
                    borderWidth: 1
                },
                {
                    label: '已解决',
                    data: closedData,
                    backgroundColor: 'rgba(75, 192, 192, 0.6)',
                    borderColor: 'rgba(75, 192, 192, 1)',
                    borderWidth: 1
                }
            ]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'top'
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    title: {
                        display: true,
                        text: '缺陷数量'
                    }
                },
                x: {
                    title: {
                        display: true,
                        text: '业务线'
                    },
                    ticks: {
                        maxRotation: 45,
                        minRotation: 0,
                        font: {
                            size: 10
                        }
                    }
                }
            },
            // 在柱子顶部显示数值
            animation: {
                onComplete: function() {
                    const chart = this;
                    const ctx = chart.ctx;
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'bottom';
                    ctx.font = 'bold 10px Arial';
                    ctx.fillStyle = '#333';
                    
                    chart.data.datasets.forEach((dataset, i) => {
                        const meta = chart.getDatasetMeta(i);
                        meta.data.forEach((bar, index) => {
                            const data = dataset.data[index];
                            if (data > 0) { // 只显示大于0的数值
                                ctx.fillText(data, bar.x, bar.y - 2);
                            }
                        });
                    });
                }
            }
        }
    });
}

// 更优化的版本 - 在柱子顶部显示数值
function renderCreatorChart(creatorStats) {
    const ctx = document.getElementById('defect-creator-chart');
    if (!ctx) return;
    
    // 获取前15个创建人
    const topCreators = Object.entries(creatorStats)
        .sort(([,a], [,b]) => b - a)
        .slice(0, 15);
    
    const labels = topCreators.map(([creator]) => creator);
    const data = topCreators.map(([, count]) => count);
    
    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: '缺陷数量',
                data: data,
                backgroundColor: 'rgba(54, 162, 235, 0.8)',
                borderColor: 'rgba(54, 162, 235, 1)',
                borderWidth: 1,
                // 使用动画在柱子顶部显示数值
                datalabels: {
                    display: true,
                    align: 'top',
                    anchor: 'end'
                }
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: false
                },
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            return '缺陷数量: ' + context.parsed.y;
                        }
                    }
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    title: {
                        display: true,
                        text: '缺陷数量'
                    }
                },
                x: {
                    title: {
                        display: true,
                        text: '创建人'
                    },
                    ticks: {
                        maxRotation: 0,
                        minRotation: 0,
                        font: {
                            size: 10
                        }
                    }
                }
            },
            // 使用动画效果显示数值
            animation: {
                onComplete: function() {
                    const chart = this;
                    const ctx = chart.ctx;
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'bottom';
                    ctx.font = 'bold 11px Arial';
                    ctx.fillStyle = '#333';
                    
                    chart.data.datasets.forEach((dataset, i) => {
                        const meta = chart.getDatasetMeta(i);
                        meta.data.forEach((bar, index) => {
                            const data = dataset.data[index];
                            ctx.fillText(data, bar.x, bar.y - 5);
                        });
                    });
                }
            }
        }
    });
}

// 更新图表颜色配置
function updateDefectStatusChart(statusStats) {
    const chartContainer = document.getElementById('defect-status-chart');
    if (!chartContainer) return;
    
    if (chartContainer.chart) {
        chartContainer.chart.destroy();
    }
    
    const labels = Object.keys(statusStats);
    const data = Object.values(statusStats);
    const colors = [
        '#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', 
        '#9966FF', '#FF9F40', '#FF6384', '#C9CBCF'
    ];
    
    chartContainer.chart = new Chart(chartContainer, {
        type: 'doughnut',
        data: {
            labels: labels,
            datasets: [{
                data: data,
                backgroundColor: colors.slice(0, labels.length),
                borderWidth: 2
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'bottom',
                    labels: {
                        font: {
                            size: 11
                        },
                        // 在图例中显示数值
                        generateLabels: function(chart) {
                            const data = chart.data;
                            if (data.labels.length && data.datasets.length) {
                                return data.labels.map((label, i) => {
                                    const value = data.datasets[0].data[i];
                                    return {
                                        text: `${label}: ${value}`,
                                        fillStyle: data.datasets[0].backgroundColor[i],
                                        hidden: false,
                                        index: i
                                    };
                                });
                            }
                            return [];
                        }
                    }
                }
            }
        }
    });
}

function updateDefectPriorityChart(priorityStats) {
    const chartContainer = document.getElementById('defect-priority-chart');
    if (!chartContainer) return;
    
    if (chartContainer.chart) {
        chartContainer.chart.destroy();
    }
    
    const labels = Object.keys(priorityStats);
    const data = Object.values(priorityStats);
    const colors = [
        '#DC3545', '#FD7E14', '#0DCAF0', '#198754', '#6C757D', '#DEE2E6'
    ];
    
    chartContainer.chart = new Chart(chartContainer, {
        type: 'pie',
        data: {
            labels: labels,
            datasets: [{
                data: data,
                backgroundColor: colors.slice(0, labels.length),
                borderWidth: 2
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'bottom',
                    labels: {
                        font: {
                            size: 11
                        },
                        // 在图例中显示数值
                        generateLabels: function(chart) {
                            const data = chart.data;
                            if (data.labels.length && data.datasets.length) {
                                return data.labels.map((label, i) => {
                                    const value = data.datasets[0].data[i];
                                    return {
                                        text: `${label}: ${value}`,
                                        fillStyle: data.datasets[0].backgroundColor[i],
                                        hidden: false,
                                        index: i
                                    };
                                });
                            }
                            return [];
                        }
                    }
                }
            }
        }
    });
}

function updateFtDefectTable(ftDefectStats) {
    const tableBody = document.getElementById('ft-defect-table-body');
    if (!tableBody) return;
    
    tableBody.innerHTML = '';
    
    ftDefectStats.forEach(stat => {
        const row = document.createElement('tr');
        row.innerHTML = `
            <td>${stat.ft_name}</td>
            <td>${stat.total_defects}</td>
            <td>${stat.open_defects}</td>
            <td>${stat.closed_defects}</td>
            <td>${((stat.closed_defects / stat.total_defects) * 100).toFixed(1)}%</td>
        `;
        tableBody.appendChild(row);
    });
}

function updateDefectList(defectList) {
    const defectListContainer = document.getElementById('defect-list-container');
    if (!defectListContainer) return;
    
    defectListContainer.innerHTML = '';
    
    defectList.forEach(defect => {
        const defectItem = document.createElement('div');
        defectItem.className = 'defect-item';
        defectItem.innerHTML = `
            <div class="defect-header">
                <span class="defect-id">#${defect.defect_id}</span>
                <span class="defect-priority badge badge-${defect.priority.toLowerCase()}">${defect.priority}</span>
            </div>
            <div class="defect-title">${defect.title}</div>
            <div class="defect-meta">
                <span>状态: ${defect.status}</span>
                <span>业务线: ${defect.ft_name}</span>
                <span>负责人: ${defect.assignee}</span>
            </div>
        `;
        defectListContainer.appendChild(defectItem);
    });
}